
#include "Vector3.h"
#include <cmath>
#include <algorithm>

using namespace Iride;

Vector3::Vector3(): x(0.0), y(0.0), z(0.0)
{
};

Vector3::Vector3(Real fx, Real fy, Real fz): x(fx), y(fy), z(fz)
{
};

void Vector3::Swap(Vector3 &rOther)
{
	std::swap(x, rOther.x);
	std::swap(y, rOther.y);
	std::swap(z, rOther.z);
}

Real Vector3::operator[] (const size_t index) const
{
	return *(&x + index);
}

Real& Vector3::operator[] (const size_t index)
{
	return *(&x + index);
}

Vector3 Vector3::operator- (void) const
{
	Vector3 result;
	result.x = - x;
	result.y = - y;
	result.z = - z;

	return result;
}

Vector3 Vector3::operator+ (const Vector3& vec) const
{
	Vector3 result;
	result.x = x + vec.x;
	result.y = y + vec.y;
	result.z = z + vec.z;

	return result;
}

Vector3 Vector3::operator- (const Vector3& vec) const
{
	Vector3 result;
	result.x = x - vec.x;
	result.y = y - vec.y;
	result.z = z - vec.z;

	return result;
}

Vector3 Vector3::operator* (const Real& coeff) const
{
	Vector3 result;
	result.x = coeff*x;
	result.y = coeff*y;
	result.z = coeff*z;

	return result;
}

Vector3 Vector3::operator/ (const Real& coeff) const
{
	Vector3 result;
	result.x = x/coeff;
	result.y = y/coeff;
	result.z = z/coeff;

	return result;
}

Vector3& Vector3::operator+= (const Vector3& vec)
{
  *this = *this + vec;
  return *this;
}

Vector3& Vector3::operator-= (const Vector3& vec)
{
  *this = *this - vec;
  return *this;
}

Real Vector3::Dot (const Vector3& vec) const
{
	return x * vec.x + y * vec.y + z * vec.z;
}

Vector3 Vector3::Cross (const Vector3& vec) const
{
	Vector3 result;
	result.x = y * vec.z - z * vec.y;
	result.y = z * vec.x - x * vec.z;
	result.z = x * vec.y - y * vec.x;

	return result;
}

Real Vector3::Length() const
{
	return sqrt(x*x + y*y + z*z);
}

bool Vector3::Normalize()
{
	Real Den = 1.0;

	Den = x*x + y*y + z*z;

	Den = sqrt(Den);

	if (Den != 0.0)
	{
		x=x/Den;
		y=y/Den;
		z=z/Den;

		return true;
	}
	else
	{
		return false;
	}
}

Vector3 Vector3::Lerp (Vector3 vecA, Vector3 vecB, Real coeff )
{
	return vecA * coeff + vecB * (1.0 - coeff);
}

const Vector3 Vector3::Zero = Vector3(0.0f, 0.0f, 0.0f);
